﻿using EnvDTE;
using EnvDTE80;
using System;
using System.IO;
using System.Linq;
using System.Text;

namespace JoinBoxAlignPlug.修改文本
{
    public class EncodingHelper
    {
        public static Encoding Read(string FullName)
        {
            FileStream file = null;
            StreamReader str = null;
            try
            {
                file = new FileStream(FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);//FileShare才能进c盘
                var bytes = StreamToBytes(file);
                var enc = AutoEncoding(bytes[0], bytes[1], bytes[2], bytes[3]);
                if (Encoding.ASCII == enc)
                    enc = new UTF8Encoding();//无签名....如果是GBK呢?
                return enc;
            }
            finally
            {
                file?.Dispose();
                str?.Dispose();
            }
        }

        /// <summary>
        /// 签名文件编码
        /// </summary>
        /// <param name="bom"></param>
        /// <returns></returns>
        static Encoding AutoEncoding(params byte[] bom)
        {
            if (bom.Length != 4)
                throw new ArgumentException("EncodingScrutator.AutoEncoding 参数大小不等于4");

            // Analyze the BOM
            if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76)
                return Encoding.UTF7; //85 116 102 55    //utf7 aa 97 97 0 0
            //utf7 编码 = 43 102 120 90

            if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf)
                return Encoding.UTF8; //无签名 117 116 102 56
            // 130 151 160 231
            if (bom[0] == 0xff && bom[1] == 0xfe)
                return Encoding.Unicode; //UTF-16LE

            if (bom[0] == 0xfe && bom[1] == 0xff)
                return Encoding.BigEndianUnicode; //UTF-16BE

            if (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff)
                return Encoding.UTF32;

            return Encoding.ASCII; //如果返回ASCII可能是GBK、无签名 utf8
        }

        public static Encoding[] Encodings = new Encoding[]
        {
             new UTF8Encoding(),//无签名
             new UTF7Encoding(),
             new UTF32Encoding(),
             Encoding.Default,
             Encoding.Unicode,
             Encoding.BigEndianUnicode,
             Encoding.UTF7,
             Encoding.UTF8,//有签名
             Encoding.UTF32
        };

        ///<summary>
        /// 将 Stream 转成 byte[]
        ///</summary>
        public static byte[] StreamToBytes(Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }
        ///<summary>
        /// 将 byte[] 转成 Stream
        ///</summary>
        public static Stream BytesToStream(byte[] bytes)
        {
            Stream stream = new MemoryStream(bytes);
            return stream;
        }
        /* - - - - - - - - - - - - - - - - - - - - - - - -
         * Stream 和 文件之间的转换
         * - - - - - - - - - - - - - - - - - - - - - - - */
        ///<summary>
        /// 将 Stream 写入文件
        ///</summary>
        public static void StreamToFile(Stream stream, string fileName)
        {
            // 把 Stream 转换成 byte[]
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始
            stream.Seek(0, SeekOrigin.Begin);
            // 把 byte[] 写入文件
            FileStream fs = new FileStream(fileName, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(bytes);
            bw.Close();
            fs.Close();
        }
        ///<summary>
        /// 从文件读取 Stream
        ///</summary>
        public static Stream FileToStream(string fileName)
        {
            // 打开文件
            FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            // 读取文件的 byte[]
            byte[] bytes = new byte[fileStream.Length];
            fileStream.Read(bytes, 0, bytes.Length);
            fileStream.Close();
            // 把 byte[] 转换成 Stream
            Stream stream = new MemoryStream(bytes);
            return stream;
        }
    }
}
